/*
 * Copyright (c) 2011-2012 Alexander Dubu
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * o  Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * o  Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * o  Neither the name Axil nor the names of its contributors may be used to
 *    endorse or promote products derived from this software without specific
 *    prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
package axil.jsr223;

import axil.api.error.AxilException;

import javax.script.*;
import java.io.Reader;

import static axil.framework.Functions.unimplemented;

/**
 * An Axil implementation of the JSR-223 ScriptEngine interface. The JSR-223
 * interface is rather nasty, since it is not thread safe and actively
 * encourages nasty side effects between executions of different scripts. When
 * the Axil safety philosophy conflicts with the poorly designed JSR-223, then
 * safety is considered more important than exact compliance with the spec.
 */
public class AxilScriptEngine extends AbstractScriptEngine {
	/**
	 * Returns a ScriptEngineFactory for the class to which this ScriptEngine
	 * belongs.
	 *
	 * @return
	 * 	Returns the factory that created this script engine.
	 */
	public ScriptEngineFactory getFactory() {
		return new AxilEngineFactory();
	}


	/**
	 * Returns an uninitialized Bindings.
	 *
	 * @return
	 * 	Returns a Bindings object that can be used to replace the state of this
	 * 	ScriptEngine.
	 */
	public Bindings createBindings() {
		// TODO: Re-implement the JSR-223 implementation for 2.0.
		throw unimplemented();
	}


	/**
	 * Create a reasonable JSR-223 ScriptException object out of the given Axil
	 * exception.
	 */
	private ScriptException ex(AxilException e) {
		// TODO: Re-implement the JSR-223 implementation for 2.0.
		throw unimplemented();
	}


	/**
	 * Causes the immediate execution of the script whose source is the given
	 * reader. The script may be re-parsed or recompiled before execution.
	 * According to JSR-223, state left in the engine from previous executions,
	 * including variable values and compiled procedures may be visible during
	 * this execution. However, because of the functional nature of Axil and
	 * its built-in safety mechanisms, this nasty side effect never actually
	 * occurs.
	 *
	 * @param reader
	 * 	The source of the script to be executed by the script engine.
	 *
	 * @param context
	 * 	A ScriptContext exposing sets of attributes in different scopes. The
	 * 	meanings of the scopes ScriptContext.GLOBAL_SCOPE, and
	 * 	ScriptContext.ENGINE_SCOPE are defined in the specification. The
	 * 	ENGINE_SCOPE Bindings of the ScriptContext contains the bindings of
	 * 	scripting variables to application objects to be used during this script
	 * 	execution.
	 *
	 * @return
	 * 	Returns the value returned from the execution of the script. The value
	 * 	is the host application native object, not an AxilObject.
	 *
	 * @throws javax.script.ScriptException
	 * 	This exception is thrown if an error occurs in the script. The actual
	 * 	Axil exception is contained within this thrown exception.
	 *
	 * @throws NullPointerException
	 * 	This exception is thrown if either argument is null.
	 */
	public Object eval(Reader reader, ScriptContext context)
	throws ScriptException {
		try {
			// TODO: Re-implement the JSR-223 implementation for 2.0.
			throw unimplemented();
		} catch (AxilException e) {
			throw ex(e);
		}
	}


	/**
	 * Causes the immediate execution of the script whose source is the String
	 * passed as the first argument.  The script may be re-parsed or recompiled
	 * before execution.  According to JSR-223, state left in the engine from
	 * previous executions, including variable values and compiled procedures
	 * may be visible during this execution. However, because of the functional
	 * nature of Axil and its built-in safety mechanisms, this nasty side
	 * effect never actually occurs.
	 *
	 * @param script
	 * 	The script to be executed by the script engine.
	 *
	 * @param context
	 * 	A ScriptContext exposing sets of attributes in different scopes. The
	 * 	meanings of the scopes ScriptContext.GLOBAL_SCOPE, and
	 * 	ScriptContext.ENGINE_SCOPE are defined in the specification. The
	 * 	ENGINE_SCOPE Bindings of the ScriptContext contains the bindings of
	 * 	scripting variables to application objects to be used during this script
	 * 	execution.
	 *
	 * @return
	 * 	Returns the value returned from the execution of the script. The value
	 * 	is the host application native object, not an AxilObject.
	 *
	 * @throws javax.script.ScriptException
	 * 	This exception is thrown if an error occurs in the script. The actual
	 * 	Axil exception is contained within this thrown exception.
	 *
	 * @throws NullPointerException
	 * 	This exception is thrown if either argument is null.
	 */
	public Object eval(String script, ScriptContext context)
	throws ScriptException {
		try {
			// TODO: Re-implement the JSR-223 implementation for 2.0.
			throw unimplemented();
		} catch (AxilException e) {
			throw ex(e);
		}
	}
}
